package com.nmc.webapp.action;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.rowset.serial.SerialBlob;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.hibernate.Hibernate;

import com.nmc.common.BirthStatusEnum;
import com.nmc.common.UserTypeEnum;
import com.nmc.service.comm.CommunicationGateway;
import com.nmc.service.manager.BirthManager;
import com.nmc.service.manager.ZonesManager;
import com.nmc.service.model.Birth;
import com.nmc.service.model.Comments;
import com.nmc.service.model.Hospital;
import com.nmc.service.model.User;
import com.nmc.service.model.Zones;

/**
 * Action to allow all birth related operations.
 * 
 */
public class BirthAction extends BaseAction {
    private static final long serialVersionUID = 6558317334878272308L;
    
    /**
     * The communicationGateway
     */
    protected CommunicationGateway communicationGateway = null;
    
    //private static final String SMS_API_USER_NAME = "gleam";
    //private static final String SMS_API_PASSWORD = "gleam123";
    //private static final String SMS_API_SENDER_ID = "NMC";
    private static final String SMS_MESSAGE = "Congratulations !!! Your baby's birth certificate generation has initiated from the hospital. We will inform once it is ready";
    private Birth birth;
     
    private String searchId;
    private List<Birth> birthList;
    private List<Birth> zDeliveryUpdateSearch;
    private String id;
    private String query;
    private File file;
    private String fileContentType;
    private String fileFileName;
    private boolean isCreate = true;
    private String birthStatus = BirthStatusEnum.Draft.name();
    private static byte[] idImage;
    private Integer zoneId;
    private List<Hospital> zoneHospitalList = null;
    
    
    private List<Zones> zones = null;
    
    /**
     * Declared to hold data privately for sometime
     */
    private Long mobileNumber;
    private Blob photoId;
    
    private List<String> ageList = new ArrayList<String>();
    private List<String> educationLevels = new ArrayList<String>();
    private List<String> religions = new ArrayList<String>();
    private List<String> attentionTypes = new ArrayList<String>();
    private List<String> numOfChildren = new ArrayList<String>();
    private List<String> deliveryType = new ArrayList<String>();
    private List<String> resPlaceTypes = new ArrayList<String>();
    private List<String> birthTypeList = new ArrayList<String>();
    
    /**
     * This will have list of hospital registered with system, last item will be others allowing to enter in case of non availibility
     */
    private List<String> birthPlaces = new ArrayList<String>();
    
    public BirthAction() {
		init();
	}
    
    
    public void setZones(List<Zones> zones) {
		this.zones = zones;
	}


	public List<Zones> getZones() {
		if(zones == null){
			zones = zonesManager.getZoness();
		}
		return zones;
	}
	
	public void setZonesManager(ZonesManager zonesManager) {
		this.zonesManager = zonesManager;
	}


	public ZonesManager getZonesManager() {
		return zonesManager;
	}
    public void init() {
    	for (int i=10; i<=70; i++){
    		ageList.add(Integer.toString(i));
    	}
    	
    	for (int i = 0; i <= 10; i++){
    		numOfChildren.add(Integer.toString(i));
    	}
    	
    	educationLevels.add("Post Graducate");
    	educationLevels.add("Graducate");
    	educationLevels.add("Higher Secondary");
    	educationLevels.add("Secondary");
    	
    	religions.add("Hindu");
    	religions.add("Muslim");
    	religions.add("Christian");
    	religions.add("Other");
    	educationLevels.add("Below Secondary");
    	
    	attentionTypes.add("Institutional - Government");
    	attentionTypes.add("Institutional - private, Non-Government");
    	attentionTypes.add("Doctor, Nurse or trained midwife");
    	attentionTypes.add("Traditional Birth attendant");
    	attentionTypes.add("Relative or others");
    	
    	deliveryType.add("Natural");
    	deliveryType.add("Caesarean");
    	deliveryType.add("Forceps/Vacuum");
    	
    	resPlaceTypes.add("City");
    	resPlaceTypes.add("Town");
    	resPlaceTypes.add("Village");
    	
    	birthPlaces.add("Hospital 1");
    	birthPlaces.add("Hospital 2");
    	birthPlaces.add("Others");
    	
    	birthTypeList.add("Single");
    	birthTypeList.add("Twins");
    	birthTypeList.add("Triplets");
    	
//    	birthManager.getNextBirthCounterForHospital(1, 2012);
    	
    }
    
	public List<String> getAgeList() {
		return ageList;
	}



	public void setAgeList(List<String> ageList) {
		this.ageList = ageList;
	}



	public List<String> getEducationLevels() {
		return educationLevels;
	}
	public void setEducationLevels(List<String> educationLevels) {
		this.educationLevels = educationLevels;
	}
	public List<String> getReligions() {
		return religions;
	}
	public void setReligions(List<String> religions) {
		this.religions = religions;
	}
	public String getSearchId() {
		return searchId;
	}

	public void setSearchId(String searchId) {
		this.searchId = searchId;
	}

	BirthManager birthManager;
    
    

    public BirthManager getBirthManager() {
		return birthManager;
	}



	public void setBirthManager(BirthManager birthManager) {
		this.birthManager = birthManager;
	}


	
    public Birth getBirth() {
		return birth;
	}



	public void setBirth(Birth birth) {
		this.birth = birth;
	}

	 public String cancel() {
		 
		    if ("zoneSearch".equals(from) && zoneId != null) {
	            return "zBirthList";
	        } else if ("hospitalSearch".equals(from)){
	        	return "searchBirth";
	        }
	        
	        return "cancel";
	    }

	/**
     * When method=GET, "input" is returned. Otherwise, "success" is returned.
     * @return cancel, input or success
     */
    public String execute() {
    	User user = userManager.getUserByUsername(getRequest().getRemoteUser());
    	String from = getRequest().getParameter("from");
    	if(UserTypeEnum.Admin.name().equalsIgnoreCase(user.getUserType())){
    			setBirthList(birthManager.getBirths());
    			if(StringUtils.isNotEmpty(id)){
    				birth = birthManager.getBirth(id);
    			}
//    	} else if(UserTypeEnum.Zone.name().equalsIgnoreCase(user.getUserType())){
//    		Integer zid = user.getZoneId();
//        	Birth birth = new Birth();
//        	birth.setZoneId(zid);
//        	setBirthList(birthManager.getZoneBirthList(birth));
    	} else if(UserTypeEnum.ZoneBirth.name().equalsIgnoreCase(user.getUserType()) && ! "zoneSearch".equalsIgnoreCase(from)){
    		Integer zid = user.getZoneId();
        	Birth birth = new Birth();
        	birth.setZoneId(zid);
        	setBirthList(birthManager.getZoneBirthList(birth));
    	}else if(StringUtils.isNotEmpty(id)){
    		if(user.getZoneId() != null){
    			 zoneId = user.getZoneId(); 
    		}
    		birth = birthManager.getBirth(id);
    	}else{
    		Integer hospitalId = user.getHospitalId(); 
    		if(hospitalId != null){
    			setBirthList(birthManager.getHospitalBirthList(hospitalId));
    		}
    	}
    	
    	
         return SUCCESS;
    }

    public String appBirth(){
    	
    	if(StringUtils.isNotEmpty(id)){
    		try {
				Birth dbbirth = birthManager.getBirth(id);
				
				dbbirth.setStatus(BirthStatusEnum.Approved.name());
				dbbirth.setRegistrationNumber(birth.getRegistrationNumber()); 
				if(StringUtils.isNotEmpty(birth.getComment())){
					Comments comment = new Comments();
					comment.setBirth(dbbirth);
					comment.setComments(birth.getComment());
					comment.setCreatedOn(new Date());
					comment.setUserId(userManager.getUserByUsername(getRequest().getRemoteUser()).getId());
					Set com = new HashSet();
					com.add(comment);
					dbbirth.setComments(com);
				}
				//TODO:: Deepak Add comments here 
				saveMessage(getText("birth.approve.success"));
				birthManager.saveBirth(dbbirth);
				
				//Send Mail ans SMS
				
			} catch (Exception e) {
				addActionError(getText("birth.approve.error" ));
				e.printStackTrace();
				return INPUT;
			}
    	}
    	return "zBirthList";
    }
    
    public String rejBirth()
    {
    	if(StringUtils.isNotEmpty(id)){
    		try {
				Birth dbbirth = birthManager.getBirth(id);
				dbbirth.setStatus(BirthStatusEnum.Rejected.name());
				if(StringUtils.isNotEmpty(birth.getComment())){
					Comments comment = new Comments();
					comment.setBirth(dbbirth);
					comment.setComments(birth.getComment());
					comment.setCreatedOn(new Date());
					comment.setUserId(userManager.getUserByUsername(getRequest().getRemoteUser()).getId());
					Set com = new HashSet();
					com.add(comment);
					dbbirth.setComments(com);
				}
				saveMessage(getText("birth.reject.success"));
				birthManager.saveBirth(dbbirth);
				
				//Send Mail ans SMS
				
			} catch (Exception e) {
				addActionError(getText("birth.reject.error" ));
				e.printStackTrace();
				return INPUT;
			}
    	}
    	return "zBirthList";
    }
    
	public void showImage() {
		try {

			if (StringUtils.isNotEmpty(id)) {
				birth = birthManager.getBirth(id);
			}

			if (birth.getIdProof() != null) {
				photoId = birth.getIdProof();
				HttpServletResponse response = ServletActionContext
						.getResponse();
				response.reset();
				response.setContentType("multipart/form-data");

				idImage = birth.getIdProof().getBytes(1,
						(int) birth.getIdProof().length());

				OutputStream out = response.getOutputStream();
				 
				out.write(idImage);
				out.flush();
				out.close();
			}

		} catch (SQLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
    /**
     * Returns "input"
     * @return "input" by default
     */
    public String doDefault() {
        return INPUT;
    }
    
    public String editRecord(){
    	return "edit";
    }

    /**
     * Save the user, encrypting their passwords if necessary
     * @return success when good things happen
     * @throws Exception when bad things happen
     */
    public String save() throws Exception {
    	HttpServletRequest request = getRequest();
        	
    	try {
			User user = userManager.getUserByUsername(request.getRemoteUser());
			Hospital hospital = new Hospital();
			hospital.setId(new Long(user.getHospitalId()));
			
			if(file != null){
				 FileInputStream fi = new FileInputStream(file);

		          Blob blob = Hibernate.createBlob(fi);
		          birth.setIdProof(blob);
			}
			if(file == null && idImage != null){
		          Blob blob = new SerialBlob(idImage);
		          birth.setIdProof(blob);
			}
			if(birth.getId() == null || "".equalsIgnoreCase(birth.getId())){
				birth.setCreatedOn(new Date());
			}
			birth.setUpdatedBy(user.getId());
			birth.setUpdatedOn(new Date());
			birth.setHospital(hospital);
			birth.setStatus(birthStatus);
			
			int year = getBirthYear(birth.getBirthDate());
			//birth.setBirthId(generatedBirthId);
			if(StringUtils.isEmpty(birth.getId())) {
				//if birthId not present
				String generatedBirthId = birthManager.getNextBirthCounterForHospital(hospital.getId().intValue(), year);
				birth.setId(generatedBirthId);
			}
			birth = birthManager.saveBirth(birth);
			
			if ( ( birth.getChildName2() != null && !birth.getChildName2().equalsIgnoreCase("") ) || 
				( birth.getSex2() != null && ! birth.getSex2().equalsIgnoreCase("-1") ) ||
				birth.getBirthWeight2() != null ) {
				String generatedBirthId = birthManager.getNextBirthCounterForHospital(hospital.getId().intValue(), year);
				birth.setId(generatedBirthId);
				birth.setChildName(birth.getChildName2());
				birth.setSex(birth.getSex2());
				birth.setBirthWeight(birth.getBirthWeight2());
				//if birthId not present in request
				//String generatedBirthId = birthManager.getNextBirthCounterForHospital(hospital.getId().intValue(), year);
				//birth.setBirthId(generatedBirthId);
				birthManager.saveBirth(birth);
			}
			if ( ( birth.getChildName3() != null && !birth.getChildName3().equalsIgnoreCase("") ) || 
					( birth.getSex3() != null && ! birth.getSex3().equalsIgnoreCase("-1") ) ||
					birth.getBirthWeight3() != null ) {
						
				String generatedBirthId = birthManager.getNextBirthCounterForHospital(hospital.getId().intValue(), year);
				birth.setId(generatedBirthId);
				birth.setChildName(birth.getChildName3());
				birth.setSex(birth.getSex3());
				birth.setBirthWeight(birth.getBirthWeight3());
				
				//if birthId not present in request
				//String generatedBirthId = birthManager.getNextBirthCounterForHospital(hospital.getId().intValue(), year);
				//birth.setBirthId(generatedBirthId);
				
				birthManager.saveBirth(birth);
			}
			id= ""+birth.getId();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			addActionError(getText("birth.create.error" ));
			return INPUT;
		}
		 if ("list".equals(from)) {
	            // add success messages
	            saveMessage(getText("birth.save"));
	            return "searchBirth";
	        }
		 mobileNumber = birth.getMobileNumber();
    	birth = new Birth();
    	saveMessage(getText("birth.create.success"));
        return SUCCESS;
    }
	private int getBirthYear(Date birthDate) {
		Calendar c = Calendar.getInstance();
		c.setTime(birthDate);
		int year = c.get(Calendar.YEAR);
		return year;
	}
    
	/*
	private void sendSMS(){
		try {
			//Date mydate = new Date(System.currentTimeMillis());

			//URL url = new URL("http://ctr.beyondmobile.co.in/sendhttp.php?user=gleam&password=gleam123&mobiles=9823362562&message=Hello I am back again&sender=NMC");
			String serverURL = "http://ctr.beyondmobile.co.in/sendhttp.php?user=%s&password=%s&mobiles=%s&message=%s&sender=%s";
			//serverURL += "&route=4";
			String mobileNumbers = "9823362562,9890299349,9371044459,9860579495,9028462392";
			String message = "Hurreyyy... Test message from NMC BD System. Confirm if you received successfully.";
			serverURL = String.format(serverURL, SMS_API_USER_NAME, SMS_API_PASSWORD, mobileNumber , URLEncoder.encode(SMS_MESSAGE, "UTF-8"), SMS_API_SENDER_ID);
			URL url = new URL(serverURL);
			
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			conn.setRequestMethod("GET");
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			conn.connect();
			BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line;
			StringBuffer buffer = new StringBuffer();
			while ((line = rd.readLine()) != null)
			{
				buffer.append(line).append("\n");
			}
				System.out.println(buffer.toString());
				rd.close();
				conn.disconnect();
			}catch(Exception e)
			{
				e.printStackTrace();
			}
	}
    public static void main(String [ ] args){
    	//string containing date in one format
        String strDate = "31-Aug-2012 22:27:01";
       
        try
        {
          //create SimpleDateFormat object with source string date format
          SimpleDateFormat sdfSource = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss");
         
          //parse the string into Date object
          Date date = sdfSource.parse(strDate);
         
          //create SimpleDateFormat object with desired date format
          SimpleDateFormat sdfDestination = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
         
          //parse the date into another format
          strDate = sdfDestination.format(date);
         
          System.out.println("Date is converted from dd/MM/yy format to MM-dd-yyyy hh:mm:ss");
          System.out.println("Converted date is : " + strDate);
          //sendSMS();
        }
        catch(Exception pe)
        {
          System.out.println("Parse Exception : " + pe);
        }
    }*/
	
    public String submitBirth(){
    	String ret = SUCCESS;
		try {
			birthStatus = BirthStatusEnum.Submit.name();
			if(file == null && idImage == null){
				addFieldError("file", getText("errors.requiredField", new String[] {getText("uploadForm.file")}));
				return INPUT;
			}
			ret = save();
			if(ret.equalsIgnoreCase(SUCCESS)) {
				//Get the mobile from birth record
				communicationGateway.sendSMS(Long.toString(mobileNumber), SMS_MESSAGE);
				ret = "submitSuccess";
				removePreviousMessage();
				saveMessage(getText("birth.submit.success"));
			}
		} catch (Exception e) {
			e.printStackTrace();
			addActionError(getText("birth.create.error" ));
			return INPUT;
		}
    	return ret;
    }
    
    public String updateCertificateDeliveryDetails(){
    	try{
    		birthManager.updateDeliveryDetails(birth.getSearchRefId(), birth);
    	}catch (Exception e) {
    		return ERROR;
    	}
    	return SUCCESS;
    }
    public String search() throws Exception {
    	HttpServletRequest request = getRequest();
    	    	
    	User user = userManager.getUserByUsername(request.getRemoteUser());
    	if (UserTypeEnum.Hospital.toString().equals(user.getUserType())) {
    		int hospitalId = user.getHospitalId();
        	birth.setHospitalId(new Long(hospitalId));
        	birthList = birthManager.searchBirth(birth);
    	} else if (UserTypeEnum.ZoneBirth.toString().equals(user.getUserType())) {
    		zoneId = user.getZoneId();
        	if(birth == null){
        		birth = new Birth();
        	}
        	birth.setZoneId(zoneId);
        	birthList = birthManager.getZoneBirthList(birth);
    	} else if (UserTypeEnum.Admin.toString().equals(user.getUserType())) {
    		if(birth == null){
        		birth = new Birth();
        	}
    		birthList = birthManager.searchBirthForAdminUser(birth);
    	}
    	
    	
    	return SUCCESS;
    }
    
    public String zoneBirthList(){
    	zoneId = userManager.getUserByUsername(getRequest().getRemoteUser()).getZoneId();
    	if(birth == null){
    		birth = new Birth();
    		birth.setZoneId(zoneId);
    	}
    	birthList = birthManager.getZoneBirthList(birth);
    	return SUCCESS;
    }
    
    public String searchBirthForDeliveryUpdate(){
    	zoneId = userManager.getUserByUsername(getRequest().getRemoteUser()).getZoneId();
    	if(birth == null){
    		birth = new Birth();
    		
    	}
    	birth.setZoneId(zoneId);
    	birthList = birthManager.getZoneBirthList(birth);
    	//return "zDeliveryUpdateSearch";
    	return SUCCESS;
    }
    
    public String viewSearchRecords() throws Exception {
    	return SUCCESS;
    }
    
    public String print() throws Exception {
    	return "submitSuccess";
    }
    
   	public void setBirthList(List<Birth> birthList) {
		this.birthList = birthList;
	}

	public List<Birth> getBirthList() {
		return birthList;
	}
	
	

	public List<Birth> getzDeliveryUpdateSearch() {
		return zDeliveryUpdateSearch;
	}
	public void setzDeliveryUpdateSearch(List<Birth> zDeliveryUpdateSearch) {
		this.zDeliveryUpdateSearch = zDeliveryUpdateSearch;
	}
	public void setId(String id) {
		this.id = id;
	}

	public String getId() {
		return id;
	}
    
	public void setQ(String q) {
        this.query = q;
    }

	public void setFile(File file) {
		this.file = file;
	}

	public File getFile() {
		return file;
	}

	public void setFileContentType(String fileContentType) {
		this.fileContentType = fileContentType;
	}

	public String getFileContentType() {
		return fileContentType;
	}

	public void setFileFileName(String fileFileName) {
		this.fileFileName = fileFileName;
	}

	public String getFileFileName() {
		return fileFileName;
	}

	public static void setIdImage(byte[] idImage) {
		BirthAction.idImage = idImage;
	}

	public static byte[] getIdImage() {
		return idImage;
	}

	public void setZoneId(Integer zoneId) {
		this.zoneId = zoneId;
	}

	public Integer getZoneId() {
		return zoneId;
	}
	public String getBirthStatus() {
		return birthStatus;
	}
	public void setBirthStatus(String birthStatus) {
		this.birthStatus = birthStatus;
	}
	public List<String> getAttentionTypes() {
		return attentionTypes;
	}
	public void setAttentionTypes(List<String> attentionTypes) {
		this.attentionTypes = attentionTypes;
	}
	public List<String> getNumOfChildren() {
		return numOfChildren;
	}
	public void setNumOfChildren(List<String> numOfChildren) {
		this.numOfChildren = numOfChildren;
	}
	public List<String> getDeliveryType() {
		return deliveryType;
	}
	public void setDeliveryType(List<String> deliveryType) {
		this.deliveryType = deliveryType;
	}
	public List<String> getResPlaceTypes() {
		return resPlaceTypes;
	}
	public void setResPlaceTypes(List<String> resPlaceTypes) {
		this.resPlaceTypes = resPlaceTypes;
	}
	public List<String> getBirthPlaces() {
		return birthPlaces;
	}
	public void setBirthPlaces(List<String> birthPlaces) {
		this.birthPlaces = birthPlaces;
	}
	public void setZoneHospitalList(List<Hospital> zoneHospitalList) {
		this.zoneHospitalList = zoneHospitalList;
	}
	public List<String> getBirthTypeList() {
		return birthTypeList;
	}
	public void setBirthTypeList(List<String> birthTypeList) {
		this.birthTypeList = birthTypeList;
	}
	public List<Hospital> getZoneHospitalList() {
		if(zoneId != null && zoneHospitalList == null){
			zoneHospitalList = hospitalManager.searchHospital(zoneId, null);
		}
		return zoneHospitalList;
	}
	public CommunicationGateway getCommunicationGateway() {
		return communicationGateway;
	}
	public void setCommunicationGateway(CommunicationGateway communicationGateway) {
		this.communicationGateway = communicationGateway;
	}

	
}
